﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Toolkit.Web.Infastructure;
using System.Web;
using Toolkit.Web.ExtensionMethods;

namespace Toolkit.Web.ViewComponents.Button
{
    public sealed class Button : ViewComponentBase
    {
        public Button(IViewComponentWriter writer, ButtonType type)
            : base(writer)
        {
            Type = type;
            IsEnabled = true;
            PrimaryIconHtmlAttributes = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
            SecondaryIconHtmlAttributes = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
            Menu = new ButtonMenu();
            ClientEventHandlers = new ClientEventHandlers();
            HtmlBuilder = new ButtonHtmlBuilder(this);

            LinkToUrl = "#";
            InputType = "submit";
        }

        public bool IsEnabled
        {
            get;
            set;
        }

        public ButtonType Type
        {
            get;
            private set;
        }

        public IHtmlString Title
        {
            get;
            set;
        }

        public string LinkToUrl
        {
            get;
            set;
        }

        public string LinkToTarget
        {
            get;
            set;
        }

        public string InputType
        {
            get;
            set;
        }

        public string InputName
        {
            get;
            set;
        }

        public string InputValue
        {
            get;
            set;
        }

        public ButtonDisplay PrimaryIconDisplay
        {
            get;
            set;
        }

        public IDictionary<string, object> PrimaryIconHtmlAttributes
        {
            get;
            private set;
        }

        public ButtonDisplay SecondaryIconDisplay
        {
            get;
            set;
        }

        public IDictionary<string, object> SecondaryIconHtmlAttributes
        {
            get;
            private set;
        }

        public ButtonMenu Menu
        {
            get;
            private set;
        }

        public bool IsMenuAllowed
        {
            get
            {
                return (
                    Type == ButtonType.DropDownButton || 
                    Type == ButtonType.SplitButton || 
                    Type == ButtonType.SplitLinkButton || 
                    Type == ButtonType.SplitInputButton
                );
            }
        }

        public ClientEventHandlers ClientEventHandlers
        {
            get;
            set;
        }

        private void ValidateConfiguration()
        {
            // Verify button supports menu if a menu is given.
            if (!IsMenuAllowed && (Menu.OverrideTemplate != null || Menu.Sections.Count > 0))
            {
                throw new NotSupportedException("Menus are not supported for the given button type.");
            }

            // Verify button supports secondary icon.
            if (!IsMenuAllowed && SecondaryIconDisplay != ButtonDisplay.None)
            {
                throw new NotSupportedException("Secondary (menu) icon is not supported for the given button type.");
            }

            // Verify a url was given if button is a link button.
            if ((Type == ButtonType.LinkButton || Type == ButtonType.SplitLinkButton) && string.IsNullOrEmpty(LinkToUrl))
            {
                throw new NotSupportedException("A link url is required for this button type.");
            }

            // Verify an input type was given if button is an input button.
            if (Type == ButtonType.InputButton && string.IsNullOrEmpty(InputType))
            {
                throw new NotSupportedException("An input type is required for this button type.");
            }
        }

        public override void WriteHtml(IViewComponentWriter writer)
        {
            ValidateConfiguration();
            base.WriteHtml(writer);
        }
    }
}
